package com.ruoyi.question.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.ruoyi.common.enums.QuestionTypeEnum;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.viewmodel.QuestionVo;
import com.ruoyi.common.viewmodel.question.QuestionEditItemVM;
import com.ruoyi.common.viewmodel.question.QuestionEditRequestVM;
import com.ruoyi.common.viewmodel.question.QuestionPageRequestVM;
import com.ruoyi.common.viewmodel.question.QuestionResponseVM;
import com.ruoyi.question.domain.QuestionItemObject;
import com.ruoyi.question.domain.QuestionObject;
import com.ruoyi.textcontent.domain.TextContent;
import com.ruoyi.textcontent.service.ITextContentService;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.question.mapper.QuestionMapper;
import com.ruoyi.question.domain.Question;
import com.ruoyi.question.service.IQuestionService;
import com.ruoyi.common.core.text.Convert;

/**
 * 题目信息Service业务层处理
 *
 * @author ruoyi
 * @date 2023-06-23
 */
@Service
public class QuestionServiceImpl implements IQuestionService {

    protected final static ModelMapper modelMapper = ModelMapperSingle.Instance();

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private ITextContentService contentService;

    /**
     * 查询题目信息
     *
     * @param id 题目信息主键
     * @return 题目信息
     *     根据自己之前设置的VO回显页面数据,题目具体信息返回的为content的JSON数据，前端暂无具体对应的表单
     */
    @Override
    public QuestionVo selectQuestionById(Long id) {
        Question question = questionMapper.selectQuestionById(id);
        QuestionVo questionVo = new QuestionVo();
        TextContent textContent = contentService.selectTextContentById(question.getTextContentId());
        questionVo.setContent(textContent.getContent());
        BeanUtils.copyProperties(question, questionVo);
        return questionVo;
    }

    @Override
    public List<Question> selectQuestionByIds(List<Long> ids) {
        return questionMapper.selectQuestionByIds(ids);
    }


    /**
     * 查询题目信息列表
     *
     * @param requestVM 题目页面信息
     * @return 题目信息
     */
    @Override
    public List<QuestionResponseVM> selectQuestionList(QuestionPageRequestVM requestVM) {

        // 查询过滤结果集合
        List<Question> questions = questionMapper.selectQuestionList(requestVM);

        // 遍历得到题目ID集合并存入数组列表
        List<Long> collect = questions.stream().map(item -> {
            Long textContentId = item.getTextContentId();

            return textContentId;
        }).collect(Collectors.toList());

        // 根据ID集合得到文本信息集合
        List<TextContent> textContents = contentService.selectTextContentByIds(collect);

        // 构建返回页面数据
        List<QuestionResponseVM> questionResponseVMS = new ArrayList<>();
        for (int i = 0; i < questions.size(); i++) {
            QuestionResponseVM responseVM = new QuestionResponseVM();

            // 利用工具将得到的题目数据转换成json实体类，得到题目信息，去除无关的html标签，作为题目信息返回
            QuestionObject questionObject = JsonUtil.toJsonObject(textContents.get(i).getContent(), QuestionObject.class);
            String clearHtml = HtmlUtil.clear(questionObject.getTitleContent());
            responseVM.setShortTitle(clearHtml);

            BeanUtils.copyProperties(questions.get(i), responseVM);
            questionResponseVMS.add(responseVM);
        }

        return questionResponseVMS;
    }


    /**
     * 新增题目信息
     *
     * @param requestVM 题目信息页面数据
     * @return 结果
     *  由于前台表单提交未完善，因此直接利用表单提交会在setQuestionInfoFromVM方法报错
     *
     */
    @Override
    public int insertQuestion(QuestionEditRequestVM requestVM) {

        // 设置question相关属性
        Question question = new Question();
        BeanUtils.copyProperties(requestVM, question);
        question.setCreateTime(DateUtils.getNowDate());

        // 页面题目相关数据转JSON并保存
        TextContent textContent = new TextContent();
        setQuestionInfoFromVM(textContent, requestVM);
        contentService.insertTextContent(textContent);

        // 保存关联ID
        question.setTextContentId(textContent.getId());

        return questionMapper.insertQuestion(question);
    }

    /**
     * 修改题目信息
     *
     * @param requestVM 题目信息
     * @return 结果
     *  由于前台表单提交未完善，因此直接利用表单提交会在setQuestionInfoFromVM方法报错
     */
    @Override
    public int updateQuestion(QuestionEditRequestVM requestVM) {

        // 得到questionId
        Long id = requestVM.getId();

        // 依据ID查出关联表context的内容并修改
        Question question = questionMapper.selectQuestionById(id);
        question.setScore(requestVM.getScore());
        question.setCorrectFromVM(requestVM.getCorrect(), requestVM.getCorrectArray());

        // 根据得到的contextID修改其内容
        Long textContentId = question.getTextContentId();
        TextContent textContent = new TextContent();
        textContent.setId(textContentId);
        setQuestionInfoFromVM(textContent, requestVM);
        contentService.updateTextContent(textContent);

        return questionMapper.updateQuestion(question);
    }

    public void setQuestionInfoFromVM(TextContent infoTextContent, QuestionEditRequestVM model) {
        List<QuestionItemObject> itemObjects = model.getItems().stream().map(i ->
                {
                    QuestionItemObject item = new QuestionItemObject();
                    item.setPrefix(i.getPrefix());
                    item.setContent(i.getContent());
                    item.setItemUuid(i.getItemUuid());
                    item.setScore(ExamUtil.scoreFromVM(i.getScore()));
                    return item;
                }
        ).collect(Collectors.toList());
        QuestionObject questionObject = new QuestionObject();
        questionObject.setQuestionItemObjects(itemObjects);
        questionObject.setAnalyze(model.getAnalyze());
        questionObject.setTitleContent(model.getTitle());
        questionObject.setCorrect(model.getCorrect());
        infoTextContent.setContent(JsonUtil.toJsonStr(questionObject));
    }

    /**
     * 批量删除题目信息
     *
     * @param ids 需要删除的题目信息主键
     * @return 结果
     */
    @Override
    public int deleteQuestionByIds(String ids) {
        return questionMapper.deleteQuestionByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除题目信息信息
     *
     * @param id 题目信息主键
     * @return 结果
     */
    @Override
    public int deleteQuestionById(Long id) {
        return questionMapper.deleteQuestionById(id);
    }

    @Override
    public QuestionEditRequestVM getQuestionEditRequestVM(Question question) {
        //题目映射
        TextContent questionInfoTextContent = contentService.selectTextContentById(question.getTextContentId());
        QuestionObject questionObject = JsonUtil.toJsonObject(questionInfoTextContent.getContent(), QuestionObject.class);
        QuestionEditRequestVM questionEditRequestVM = modelMapper.map(question, QuestionEditRequestVM.class);
        questionEditRequestVM.setTitle(questionObject.getTitleContent());

        //答案
        QuestionTypeEnum questionTypeEnum = QuestionTypeEnum.fromCode(Math.toIntExact(question.getQuestionType()));
        switch (questionTypeEnum) {
            case SingleChoice:
            case TrueFalse:
                questionEditRequestVM.setCorrect(question.getCorrect());
                break;
            case MultipleChoice:
                questionEditRequestVM.setCorrectArray(ExamUtil.contentToArray(question.getCorrect()));
                break;
            case GapFilling:
                List<String> correctContent = questionObject.getQuestionItemObjects().stream().map(d -> d.getContent()).collect(Collectors.toList());
                questionEditRequestVM.setCorrectArray(correctContent);
                break;
            case ShortAnswer:
                questionEditRequestVM.setCorrect(questionObject.getCorrect());
                break;
            default:
                break;
        }
        questionEditRequestVM.setScore(Long.valueOf(ExamUtil.scoreToVM(Math.toIntExact(question.getScore()))));
        questionEditRequestVM.setAnalyze(questionObject.getAnalyze());


        //题目项映射
        List<QuestionEditItemVM> editItems = questionObject.getQuestionItemObjects().stream().map(o -> {
            QuestionEditItemVM questionEditItemVM = modelMapper.map(o, QuestionEditItemVM.class);
            if (o.getScore() != null) {
                questionEditItemVM.setScore(ExamUtil.scoreToVM(o.getScore()));
            }
            return questionEditItemVM;
        }).collect(Collectors.toList());
        questionEditRequestVM.setItems(editItems);
        return questionEditRequestVM;
    }
}
